# coding=utf-8
# 2020/4/1: 首个记录
# 2020/6/3: 支持插件版本3.1，增加Agency.create_bus_message/send_bus_message以及Util.send_bus_message
# 2020/8/5: 添加EnumValue类
# 2020/8/18: 支持插件版本3.2，增加Util.add_hits_to_histline_report

# 插件主版本
plugin_ver_major = 3

# 插件次版本
plugin_ver_minor = 2

# 是否为独立运行模式
standalone = True

# 全局公共路径
global_public_path = ""

# 当前时间戳
time = 0.0

# 循环时间戳间隔
interval = 0.0

# 当前session
session = None

# 当前session的公共路径
session_public_path = ""

# 输入样本表
input_samples = {}

# 输出样本表
output_samples = {}

# 报告本地ID至全局ID映射表
report_id_table = {}


# 枚举值
class EnumValue:
    def __init__(self, val):
        self.val = val

    def __eq__(self, other):
        return self.val == other.val

    def __ne__(self, other):
        return self.val != other.val

    def __trunc__(self):
        return self.val


# 通用样本
class GeneralSample:
    def __init__(self):
        self.protocol = ""  # 样本协议名
        self.time = 0.0  # 样本时间戳
        self.values = []  # 样本数据
        self.significant = 0  # 样本关键数据个数


# 通用样本对
class GeneralSamplePair:
    def __init__(self):
        self.sample1 = GeneralSample()  # 样本1
        self.weight1 = 0.0  # 样本1权重
        self.sample2 = GeneralSample()  # 样本2
        self.weight2 = 0.0  # 样本2权重


# 场景片段索引
class Scene:
    def __init__(self):
        self.id = ""  # 场景类别ID
        self.begin = 0.0  # 场景片段开始时间
        self.length = 0.0  # 场景片段长度
        self.properties = []  # 场景属性


# 总线报文
class BusMessage:
    def __init__(self):
        self.channel = 0  # 总线通道，1~16
        self.id = 0  # 报文ID
        self.periodic = False  # 是否为周期发送
        self.period = 0  # 报文发送周期（仅当periodic为True时有效），ms
        self.data = []  # 报文数据


# 代理者
class Agency:
    def __init__(self):
        pass

    @staticmethod
    def create_general_sample():
        return GeneralSample()

    @staticmethod
    def create_general_sample_pair():
        return GeneralSamplePair()

    @staticmethod
    def create_bus_message():
        return BusMessage()

    @staticmethod
    def create_scene():
        return Scene()

    @staticmethod
    def get_global_param(key):
        return None

    @staticmethod
    def set_global_param(key, value):
        pass

    @staticmethod
    def add_scene(sess, scene):
        print("add_scene: ", scene.id, scene.begin, scene.length, scene.properties)

    @staticmethod
    def update_report(sess, global_id, parameters):
        print("update_report: ", global_id, parameters)

    @staticmethod
    def send_bus_message(msg):
        print("send_bus_message: ", msg.channel, msg.id, msg.period if msg.periodic else -1, msg.data)


# 代理者对象
agency = Agency()


# 实用工具
class Util:
    def __init__(self):
        pass

    @staticmethod
    def output_sample(sample):
        if sample is None or not hasattr(sample, 'protocol') or sample.protocol is None or len(sample.protocol) == 0:
            return
        protocol = sample.protocol
        if protocol not in output_samples:
            output_samples[protocol] = []
        elif not isinstance(output_samples[protocol], list):
            output_samples[protocol] = [output_samples[protocol]]
        output_samples[protocol].append(sample)

    @staticmethod
    def add_scene(scene):
        if session is None or scene is None or not hasattr(scene, 'id') or scene.id is None or len(scene.id) == 0:
            return
        agency.add_scene(session, scene)

    @staticmethod
    def set_to_value_report(id, value):
        if standalone:
            report_id_table[id] = id
        if id in report_id_table:
            agency.update_report(session, report_id_table[id], {'x_set': float(value)})

    @staticmethod
    def add_to_value_report(id, value):
        if standalone:
            report_id_table[id] = id
        if id in report_id_table:
            agency.update_report(session, report_id_table[id], {'x': float(value)})

    @staticmethod
    def add_to_numeric_histline_report(id, x, hist_value, line_value=None):
        if standalone:
            report_id_table[id] = id
        if id in report_id_table:
            agency.update_report(session, report_id_table[id], {'x': float(x), 'y': float(hist_value), 'y2': float(line_value) if line_value is not None else None})

    @staticmethod
    def add_hits_to_numeric_histline_report(id, x, hit, times=1):
        if standalone:
            report_id_table[id] = id
        if id in report_id_table:
            agency.update_report(session, report_id_table[id], {'x': float(x), 'hit': bool(hit), 'times': int(times)})

    @staticmethod
    def add_to_label_histline_report(id, label, hist_value, line_value=None):
        if standalone:
            report_id_table[id] = id
        if id in report_id_table:
            agency.update_report(session, report_id_table[id], {'x_index': int(label), 'y': float(hist_value), 'y2': float(line_value) if line_value is not None else None})

    @staticmethod
    def add_hits_to_label_histline_report(id, label, hit, times=1):
        if standalone:
            report_id_table[id] = id
        if id in report_id_table:
            agency.update_report(session, report_id_table[id], {'x_index': int(label), 'hit': bool(hit), 'times': int(times)})

    @staticmethod
    def add_to_scatter_report(id, x, y):
        if standalone:
            report_id_table[id] = id
        if id in report_id_table:
            agency.update_report(session, report_id_table[id], {'x': float(x), 'y': float(y)})

    @staticmethod
    def add_to_scatter_report_with_time(id, x, y, t):
        if standalone:
            report_id_table[id] = id
        if id in report_id_table:
            agency.update_report(session, report_id_table[id], {'x': float(x), 'y': float(y), 't': float(t), 'session': session.strftime('%Y%m%d%H%M%S')})

    @staticmethod
    def add_to_matrix_table_report(id, x, y, value):
        if standalone:
            report_id_table[id] = id
        if id in report_id_table:
            agency.update_report(session, report_id_table[id], {'x': float(x), 'y': float(y), 'z': float(value)})

    @staticmethod
    def add_to_label_table_report(id, x_label, y_label, value):
        if standalone:
            report_id_table[id] = id
        if id in report_id_table:
            agency.update_report(session, report_id_table[id], {'x_index': int(x_label), 'y_index': int(y_label), 'z': float(value)})

    @staticmethod
    def send_bus_message(channel, id, data, period=None):
        msg = agency.create_bus_message()
        msg.channel = channel
        msg.id = id
        msg.periodic = period is not None
        msg.period = period if period is not None else 0
        msg.data = data
        agency.send_bus_message(msg)

